class WeeklyResult < ActiveRecord::Base
  establish_connection :weekly
  belongs_to :weekly

  def work
    Work.find_by_wid wid
  end

  #0 = 'new'
  #-1 = except
  #>0
  #nil ??
  def last_score_rank unknown_ids = nil
    return nil if unknown_ids && unknown_ids.include?(wid)
    if last_weekly = weekly.last
      return -1 if wid == last_weekly.last.wid
      return 0 if wid > last_weekly.wid
      last_result = WeeklyResult.find_by_wid_and_weekly_id wid, last_weekly.id
      if last_result
        return last_result.score_rank
      else
        last_except = WeeklyExcept.find_by_wid_and_weekly_id wid, last_weekly.id
        return -1 if last_except
        existed_count = WeeklyResult.count :include => :weekly,
                                             :conditions => ['weeklies."index" < ? and weekly_results.wid = ?', weekly.index, wid]
        return (existed_count > 0 ? nil : 0)
      end
    end
    0
  end

  def new_rank_check last_weekly = nil, unknown_ids = nil
    return nil if unknown_ids && unknown_ids.include?(wid)
    last_weekly ||= weekly.last
    if last_weekly
      return 0 if wid > last_weekly.wid
      existed_count = WeeklyResult.count :include => :weekly,
                                           :conditions => ['weeklies."index" < ? and weekly_results.wid = ?', weekly.index, wid]
      return (existed_count > 0 ? nil : 0)
    end
    0
  end

  def is_changqi?
    corrent_results = WeeklyResult.find :all,
                                        :include => :weekly,
                                        :conditions => ["score_rank <= weeklies.rank_from and weekly_results.wid = ? and weeklies.id < ?", wid, weekly_id]
    corrent_results.size > 2 ? true : false
  end

  #周刊统计数据
  def self.stat id1, id2, except_ids
    time = Time.now
    puts "*reading data..."
    results1 = Result.find :all, :include => :work,
                           :conditions => ["results.scan_id = ? and works.status = 1", id1]
    results2 = Result.find :all, :include => :work,
                           :conditions => ["results.scan_id = ? and works.status = 1 and works.wid not in (?) and works.ac_type_id != 18", id2, except_ids]
    puts "#{Time.now - time} seconds passed.."
    results = {}
    results2.each{|r2| results[r2.work.id] = r2}
    unless results1.empty?
      results1.each do |r1|
        if results[r1.work.id]
          results[r1.work.id].clicks -= r1.clicks
          results[r1.work.id].comments -= r1.comments
          results[r1.work.id].stows -= r1.stows.to_i
          results[r1.work.id][:old] = true
        end
      end
      #删除错误数据
      last_wid = Result.maximum("works.wid", :include => :work, :conditions => ["scan_id = ?", id1]).to_i
      results_b = results.select{|i, r| !r[:old] && r.work.wid <= last_wid - 5000 }
      results_b.each{|i, r| results.delete(i)}
      results_b1 = results.select{|i, r| !r[:old] && r.work.wid <= last_wid }
      check_results = Result.all(:select => "work_id",
                                  :conditions => ["work_id in (?) and scan_id < ? and clicks > 500", results_b1.collect{|i, r| r.work_id}, id1],
                                  :group => "work_id").collect{|r| r.work.id}
      results_c = results_b1.select{|i, r| check_results.include?(r.work_id)}
      File.open(%[#{RAILS_ROOT}/config/_lost_last.yml],"w"){ |io| YAML.dump results_b.collect{|r| r.last} + results_c.collect{|r| r.last},io }
      results_c.each{|i, r| results.delete(i)}
    end
    puts "*computing..." #计算分数
    @@space_fix_cache ||= PStore.new("#{RAILS_ROOT}/config/space_fix_cache")
    @@space_fix_cache.transaction do
      results.values.each{|r| r[:point] = r.get_ranking_point}
      c_rank = nil
      l_id = nil
      #点击序
      results.values.sort_by{|r| r.clicks}.reverse.each_with_index do |r, i|
        c_rank = i + 1 if i == 0 || results[r.work.id].clicks != results[l_id].clicks
        l_id = r.work.id
        results[r.work.id][:click_rank] = c_rank
      end
      #评论序
      results.values.sort_by{|r| r.comments}.reverse.each_with_index do |r, i|
        c_rank = i + 1 if i == 0 || results[r.work.id].comments != results[l_id].comments
        l_id = r.work.id
        results[r.work.id][:comment_rank] = c_rank
      end
      #收藏序
      results.values.sort_by{|r| r.stows.to_i}.reverse.each_with_index do |r, i|
        c_rank = i + 1 if i == 0 || results[r.work.id].stows != results[l_id].stows
        l_id = r.work.id
        results[r.work.id][:stow_rank] = c_rank
      end
      #Point序
      results.values.sort_by{|r| r[:point]}.reverse.each_with_index do |r, i|
        c_rank = i + 1 if i == 0 || results[r.work.id][:point] != results[l_id][:point]
        l_id = r.work.id
        results[r.work.id][:point_rank] = c_rank
      end
    end
    puts "compute over.(#{Time.now - time} sec.)"
    results.values.sort_by{|r| r[:point_rank]}
  end
end
